package org.aceor.mddal.gateway.merger.common;

/**
 * Created by lxue on 16/4/17.
 */

import org.aceor.mddal.gateway.resultset.BaseResultSet;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.SQLException;

public abstract class AbstractMergerInvokeHandler<T extends BaseResultSet> implements InvocationHandler {

    private static final String GET = "get";
    private final T resultSet;

    protected AbstractMergerInvokeHandler(T resultSet) {
        this.resultSet = resultSet;
    }

    /**
     * 由于GroupByResultSet和AggregationResultSet结果集返回的值都是XXXValue.
     * 而正常我们是通过ResultSet.getXXX(index/name)来获取rs的值.
     * 因此这里做了层代理,凡是get方法,都会映射去取到XXXValue对象中的某个对应的值
     *
     * @param proxy
     * @param method
     * @param args
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
        if (!isGetDataMethod(method, args)) {
            return method.invoke(resultSet, args);
        }
        //执行getObject(int index),getInteger(String columnName)等等
        return doMerge(resultSet, method, new ResultSetQueryIndex(args[0]));
    }

    private boolean isGetDataMethod(final Method method, final Object[] args) {
        return method.getName().startsWith(GET) && null != args && 1 == args.length;
    }

    protected abstract Object doMerge(T resultSet, Method method, ResultSetQueryIndex resultSetQueryIndex) throws ReflectiveOperationException, SQLException;

    protected Object invokeOriginal(final Method method, final ResultSetQueryIndex resultSetQueryIndex) throws ReflectiveOperationException {
        return method.invoke(resultSet, new Object[]{resultSetQueryIndex.getRawQueryIndex()});
    }
}
